package org.kth.dks.dks_node;

/**
 * <p>Title: DKS</p>
 * <p>Description: DKS Middleware</p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: KTH-IMIT/SICS</p>
 * @author not attributable
 * @version 1.0
 */

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import org.kth.dks.dks_comm.DKSRef;

/**
 * Sorted set of Nonces (could have been implemented as a LinkedList)
 * Head element is the youngest, while the tail is the oldest
 * <p>Title: DKS</p>
 * <p>Description: DKS Middleware</p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: KTH-IMIT/SICS</p>
 * @author not attributable
 * @version 1.0
 */
public class Nonces {
  private SortedSet removedNonces;

  private static class NonceComparator implements Comparator {
    public int compare(Object o1, Object o2) {
      Long t1 = (Long)((NoncePair) o1).getTime();
      Long t2 = (Long)((NoncePair) o2).getTime();
      return o1.equals(o2) ? 0 : t1.longValue()>t2.longValue() ? -1 : 1;
    }
  }

  private static class NoncePair {
    private DKSRef ref;
    private Long time;

    public NoncePair(DKSRef ref, Long time) {
      this.ref = ref;
      this.time = time;
    }

    public DKSRef getRef() { return ref; }
    public Long getTime() { return time; }
    public boolean equals(Object o) { return ref.equals(((NoncePair)o).getRef()); }
  }

  public Nonces() {
    removedNonces = new TreeSet(new NonceComparator());
  }

  public boolean addNonce(DKSRef ref) {
    return removedNonces.add(new NoncePair(ref, new Long(new Date().getTime())));
  }

  public boolean containsNonce(DKSRef ref) {
    return removedNonces.contains(new NoncePair(ref, new Long(0)));
  }

  public List getRecent(int n) {
    Set headSet = null;
    if (removedNonces.size()<=n) headSet = removedNonces;
    else {
      NoncePair np = (NoncePair)removedNonces.first();
      for (Iterator it = removedNonces.iterator(); it.hasNext() && n >= 0; n--) {
        np = (NoncePair) it.next();
      }
      headSet=removedNonces.headSet(np);
    }

    List ret = new ArrayList();
    for (Iterator it = headSet.iterator(); it.hasNext();) {
      ret.add( ((NoncePair)it.next()).getRef() );
    }
    return ret;
  }

}
